//1. 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/tcp.h>  // For TCP header
#include <netinet/ip.h>   // For IP header
#include <arpa/inet.h>

// 计算校验和的函数（伪代码，具体实现需要更复杂）
unsigned short calculate_checksum(unsigned short *ptr, int nbytes) {
    //...
    return checksum;
}

int main() {
    int sockfd;
    char buffer[4096];
    struct iphdr *ip_header = (struct iphdr *) buffer;
    struct tcphdr *tcp_header = (struct tcphdr *) (buffer + sizeof(struct iphdr));

    // 创建原始套接字
    sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
    if (sockfd < 0) {
        perror("Could not create socket");
        return 1;
    }

    // 设置套接字选项
    int one = 1;
    const int *val = &one;
    if (setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, val, sizeof(one)) < 0) {
        perror("Error setting IP_HDRINCL");
        return 1;
    }

    // 构造 IP 头
    //...

    // 构造 TCP 头
    //...

    // 计算 TCP 头校验和
    tcp_header->check = calculate_checksum((unsigned short *) tcp_header, sizeof(struct tcphdr));

    // 发送数据包
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(80);
    sin.sin_addr.s_addr = inet_addr("192.168.1.1");

    if (sendto(sockfd, buffer, ip_header->tot_len, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
        perror("send failed");
        return 1;
    }

    // 关闭套接字
    close(sockfd);
    return 0;
}


//2. 
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <linux/if_packet.h>
#include <net/ethernet.h> /* the L2 protocols */

unsigned char dest_mac[ETH_ALEN] = {0x00, 0x14, 0x22, 0x33, 0x44, 0x55};
unsigned char src_mac[ETH_ALEN] = {0x00, 0x0C, 0x29, 0x48, 0x57, 0x66};

int main() {
    int sockfd;
    unsigned char buffer[ETH_FRAME_LEN];
    struct ethhdr *eth_header = (struct ethhdr *)buffer;

    sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
    if (sockfd == -1) {
        perror("socket");
        return 1;
    }

    // 构造以太网头部
    memcpy(eth_header->h_dest, dest_mac, ETH_ALEN);
    memcpy(eth_header->h_source, src_mac, ETH_ALEN);
    eth_header->h_proto = htons(ETH_P_IP); // 这里是假设你要构造的是IP数据包

    // 构造数据包的其他部分，比如IP头和TCP头...

    // 发送数据包
    struct sockaddr_ll socket_address;
    socket_address.sll_ifindex = if_nametoindex("eth0"); // 接口名字，如 "eth0"
    socket_address.sll_halen = ETH_ALEN;
    memcpy(socket_address.sll_addr, dest_mac, ETH_ALEN);

    if (sendto(sockfd, buffer, 64, 0, (struct sockaddr*)&socket_address, sizeof(struct sockaddr_ll)) < 0) {
        perror("send");
        return 1;
    }

    // 关闭套接字
    close(sockfd);
    return 0;
}

//3. 
https://blog.csdn.net/weixin_43844521/article/details/133658879